home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-03 | 17.8 KB | 810 lines | [TEXT/KAHL] |
- // Contains main, add this and SoundByteUtils.c to a project
- // along with MacTraps lib in Think C or compiled with the
- // usual C libraries in MPW. This has not been compiled
- // under MPW but you should have very little problems if any
- // doing so.
-
- #include <EPPC.h>
- #include <Menus.h>
- #include <Sound.h>
- #include <SoundInput.h>
- #include <AppleEvents.h>
- #include <Script.h>
-
- #include "OCEErrors.h"
- #include "DigitalSignature.h"
-
- #include "SoundByte.h"
- #include "SoundByteUtils.h"
-
- Environment gEnvironment;
-
- void BeginProcessing(OperationType operation)
- {
- Handle item;
- Rect bounds;
- Str255 message = {0};
- short kind = 0;
-
- SetCursor(*GetCursor(watchCursor));
-
- if (gEnvironment.statusDialog == nil)
- {
- gEnvironment.statusDialog = GetNewDialog(rStatusDialog, nil, kMoveToFront);
- if (gEnvironment.statusDialog == nil)
- AlertOSErr(MemError());
- SetPort(gEnvironment.statusDialog);
- }
-
- if (operation == kSigningOperation)
- kind = kSigning;
- else if (operation == kVerifyingOperation)
- kind = kVerifying;
- else if (operation == kProcessingOperation)
- kind = kProcessing;
- else if (operation == kCancelingOperation)
- kind = kCanceling;
-
- GetIndString(message, rOtherStrings, kind);
- GetDItem(gEnvironment.statusDialog, iStatus, &kind, &item, &bounds);
- SetIText(item, message);
-
- ShowWindow(gEnvironment.statusDialog);
- SetPort(gEnvironment.statusDialog);
- DrawDialog(gEnvironment.statusDialog);
- }
-
- void EndProcessing()
- {
- if (gEnvironment.statusDialog != nil)
- {
- DisposDialog(gEnvironment.statusDialog);
- gEnvironment.statusDialog = nil;
- SetPort(FrontWindow());
- DrawDialog(FrontWindow()); // force an update here
- }
-
- SetCursor(&qd.arrow);
- }
-
- pascal Boolean SimpleStatusProc()
- {
- GrafPtr savePort;
- EventRecord event;
- DialogPtr aDialog;
- short item;
- long ignore;
- Boolean keepGoing = true;
-
- GetPort(&savePort);
- SetPort(gEnvironment.statusDialog);
-
- if (WaitNextEvent(kProcessingEventMask, &event, kMinSleep, kNilMouseRgn))
- {
- if (FrontWindow() != gEnvironment.statusDialog) // just in case
- SelectWindow(gEnvironment.statusDialog);
-
- switch (event.what)
- {
- case autoKey:
- case keyDown:
- // poor mans way to cancel, see IM VI for localizable way!
- if (event.modifiers & cmdKey && (event.message & charCodeMask) == '.')
- keepGoing = false;
- break;
- default:
- SetCursor(&qd.arrow);
- if (IsDialogEvent(&event) && DialogSelect(&event, &aDialog, &item) && aDialog == gEnvironment.statusDialog)
- keepGoing = false;
- SetCursor(*GetCursor(watchCursor));
- }
-
- }
-
- if (keepGoing == false)
- {
- BeginProcessing(kCancelingOperation);
- Delay(40, &ignore); // delay so user can read the status dialog
- }
-
- SetPort(savePort);
-
- return keepGoing;
- }
-
- OSErr DoProcessData(SIGContextPtr context, SoundByteWindowPtr window)
- {
- short kind;
- Handle item;
- Rect bounds;
- Str255 topic;
- Size soundLength;
- Size soundOffset = 0;
- Size soundChunk = kOurProcessDataSize;
- OSErr error = noErr;
-
- do {
- // digest the topic field
- GetDItem((DialogPtr)window, iTopic, &kind, &item, &bounds);
- GetIText(item, topic);
- if (error = SIGProcessData(context, topic, topic[0]))
- break;
- if (SimpleStatusProc() == false) // see if user want's to cancel
- error = userCanceledErr;
-
- // if there is a sound, process it in kOurProcessDataSize chunks
- if (window->sound == nil)
- break;
- soundLength = GetHandleSize(window->sound);
- if (soundLength < soundChunk)
- soundChunk = soundLength;
- HLock(window->sound);
- do {
- if (error = SIGProcessData(context, (*window->sound)+soundOffset, soundChunk))
- break;
- if (SimpleStatusProc() == false) // see if user want's to cancel
- {
- error = userCanceledErr;
- break;
- }
- soundOffset+=soundChunk; // increment what we just processed
- if ((soundOffset + soundChunk) > soundLength) // preflight chunk for next pass
- soundChunk = soundLength - soundOffset;
- if (soundChunk <= 0) // when we process it all, bail
- break;
- } while (true);
- HUnlock(window->sound);
- } while (0);
-
- return error;
- }
-
- OSErr AssociateSignersNameAndSoundByte(SIGContextPtr context, SoundByteWindowPtr window)
- {
- SIGCertInfo certInfo;
- SIGNameAttributesInfo attrInfo;
- unsigned short attrIndex;
- OSErr error;
- Str255 attrValue = {0};
-
- do {
- // get the number of cert attributes
- if (error = SIGGetCertInfo(context, kSIGSignerCertIndex, &certInfo))
- break;
-
- // walk the attributes looking for the "right" one to store away
- for (attrIndex = 0; attrIndex < certInfo.certAttributeCount; attrIndex++)
- {
- if (error = SIGGetCertNameAttributes(context, kSIGSignerCertIndex, attrIndex, &attrInfo))
- break;
- if (attrInfo.attributeType == kSIGTitle) // in case there is no name
- BlockMove(&attrInfo.attribute, &attrValue, sizeof(Str255));
- else if (attrInfo.attributeType == kSIGCommonName) // best thing to display
- {
- BlockMove(&attrInfo.attribute, &attrValue, sizeof(Str255));
- break;
- }
- }
- if (window->partOfName)
- DisposHandle(window->partOfName);
- error = PtrToHand(attrValue, &window->partOfName, attrValue[0] + 1);
- } while (0);
-
- return error;
- }
-
- void DoVerifying()
- {
- OSErr error;
- SIGContextPtr context = nil;
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
-
- do {
- window->state = kUnkownState;
- BeginProcessing(kVerifyingOperation);
- if (error = SIGNewContext(&context))
- break;
- HLock(window->signature);
- error = SIGVerifyPrepare(context, (SIGSignaturePtr)*window->signature, GetHandleSize(window->signature), (SIGStatusProcPtr)SimpleStatusProc);
- HUnlock(window->signature);
- if (error)
- break;
- BeginProcessing(kProcessingOperation);
- if (error = DoProcessData(context, window))
- break;
- BeginProcessing(kVerifyingOperation);
- error = SIGVerify(context);
- if (error && error != kSIGInvalidCredentialErr)
- {
- window->state = kInvalidState;
- break;
- }
- if (error = AssociateSignersNameAndSoundByte(context, window)) // refresh name for safety
- break;
- window->state = kValidState;
- EndProcessing();
- error = SIGShowSigner(context, kNullPString);
- } while (0);
-
- if (context) SIGDisposeContext(context);
- EndProcessing();
-
- AlertOSErr(error);
- }
-
- void DoSigning()
- {
- OSErr error;
- Size signatureSize;
- SIGContextPtr context = nil;
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
-
- do {
- if (error = SIGNewContext(&context))
- break;
- if (error = SIGSignPrepare(context, nil, kNullPString, &signatureSize))
- break;
- BeginProcessing(kProcessingOperation);
- if (window->signature)
- SetHandleSize(window->signature, signatureSize);
- else
- window->signature = NewHandle(signatureSize);
- if (error = MemError())
- break;
- HNoPurge(window->signature);
- if (error = DoProcessData(context, window))
- break;
- BeginProcessing(kSigningOperation);
- HLock(window->signature);
- error = SIGSign(context, (SIGSignaturePtr)*window->signature, (SIGStatusProcPtr)SimpleStatusProc);
- HUnlock(window->signature);
- if (error)
- break;
- if (error = AssociateSignersNameAndSoundByte(context, window))
- break;
- window->state = kValidState;
- } while (0);
-
- if (context) SIGDisposeContext(context);
-
- if (error && window->signature)
- {
- DisposHandle(window->signature);
- window->signature = nil;
- }
-
- EndProcessing();
- AlertOSErr(error);
- }
-
- pascal void AuthorDrawProc(DialogPtr dialog, short itemNumber)
- {
- short kind;
- Handle item;
- Rect bounds;
- SoundByteWindowPtr window = (SoundByteWindowPtr)dialog;
-
- GetDItem(dialog, itemNumber, &kind, &item, &bounds);
-
- if (window->partOfName)
- {
- EraseRect(&bounds);
- MoveTo(bounds.left + 20, bounds.bottom - 4);
- DrawString((StringPtr)*window->partOfName);
-
- bounds.bottom -= 1;
- bounds.right = bounds.left + 16;
- bounds.top = bounds.bottom - 16;
-
- if (window->state == kValidState)
- kind = kSIGValidSignatureIconResID;
- else if (window->state == kInvalidState)
- kind = kSIGInvalidSignatureIconResID;
- else
- kind = kSIGSignatureIconResID;
-
- PlotIconID(&bounds, 0, 0, kind);
- }
- else
- {
- PenPat(qd.gray);
- FrameRect(&bounds);
- PenNormal();
- }
- }
-
- OSErr SaveToDisk(SoundByteWindowPtr window, short currentResFile)
- {
- OSErr error;
- short kind;
- Handle item;
- Rect bounds;
- Str255 topic;
- Handle topicHandle;
-
- do {
- GetDItem((DialogPtr)window, iTopic, &kind, &item, &bounds);
- GetIText(item, topic);
- if (error = PtrToHand(topic, &topicHandle, topic[0] + 1))
- break;
- UseResFile(window->resRef);
- RmveResource(Get1Resource(kTopicResType, kTopicResID));
- RmveResource(Get1Resource(kSoundResType, kSoundResID));
- RmveResource(Get1Resource(kNameResType, kNameResID));
- AddResource(topicHandle, kTopicResType, kTopicResID, kNullPString);
- if (error = ResError())
- break;
- if (window->signature)
- AddResource(window->signature, kSignatureResType, kSignatureResID, kNullPString);
- if (window->sound)
- AddResource(window->sound, kSoundResType, kSoundResID, kNullPString);
- if (window->partOfName)
- AddResource(window->partOfName, kNameResType, kNameResID, kNullPString);
- UpdateResFile(window->resRef);
- if (window->signature)
- DetachResource(window->signature);
- if (window->sound)
- DetachResource(window->sound);
- if (window->partOfName)
- DetachResource(window->partOfName);
- } while (0);
-
- UseResFile(currentResFile);
-
- return error;
- }
-
- void DoSaving()
- {
- short kind;
- Handle item;
- Rect bounds;
- Str255 topic;
- OSErr error;
- StandardFileReply reply;
- short currentResFile = CurResFile();
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
- Boolean fileSaved = (window->resRef != kNonExistentFileRef);
-
- if (fileSaved)
- SaveToDisk(window, currentResFile);
- else
- {
- GetDItem((DialogPtr)window, iTopic, &kind, &item, &bounds);
- GetIText(item, topic);
-
- StandardPutFile(kNullPString, topic, &reply);
-
- if (reply.sfGood)
- {
- do {
- if (reply.sfReplacing)
- {
- if (error = FSpDelete(&reply.sfFile))
- break;
- }
- FSpCreateResFile(&reply.sfFile, kSoundByteFileCreator, kSoundByteFileType, smSystemScript);
- if (error = ResError())
- break;
- window->resRef = FSpOpenResFile(&reply.sfFile, fsRdWrPerm);
- if (error = ResError())
- break;
- error = SaveToDisk(window, currentResFile);
- } while (0);
-
- AlertOSErr(error);
- }
- }
- }
-
- void DoAppleMenu(short theItem)
- {
- Str255 accName;
- short accNumber;
-
- switch (theItem)
- {
- case iAbout:
- DoAbout();
- break;
- default:
- GetItem(GetMHandle(mApple), theItem, accName);
- accNumber = OpenDeskAcc(accName);
- break;
- }
- }
-
- void DoNewSoundByte()
- {
- short kind;
- Handle item;
- Rect bounds;
- SoundByteWindowPtr window;
-
- if (window = (SoundByteWindowPtr)NewPtrClear(sizeof(SoundByteWindow)))
- {
- GetNewDialog(rSoundByteDialog, (Ptr)window, kMoveToFront);
- SetPort((WindowPtr)window);
- GetDItem((DialogPtr)window, iAuthor, &kind, &item, &bounds);
- SetDItem((DialogPtr)window, iAuthor, kind, (Handle)AuthorDrawProc, &bounds);
- window->resRef = kNonExistentFileRef;
- }
- else
- AlertOSErr(MemError());
- }
-
- void DoClose()
- {
- short currentResFile = CurResFile();
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
- Boolean fileSaved = (window->resRef != kNonExistentFileRef);
-
- if (window->signature)
- DisposHandle(window->signature);
- if (window->sound)
- DisposHandle(window->sound);
- if (window->partOfName)
- DisposHandle(window->partOfName);
-
- if (fileSaved)
- {
- CloseResFile(window->resRef);
- UseResFile(currentResFile);
- }
-
- CloseDialog((WindowPtr)window);
- DisposPtr((Ptr)window);
- }
-
- void DoOpen()
- {
- OSErr error;
- short kind;
- Handle item;
- Rect bounds;
- StandardFileReply reply;
- SoundByteWindowPtr window;
- Handle topicHandle = nil;
- short currentResFile = CurResFile();
- SFTypeList types = { kSoundByteFileType };
-
- StandardGetFile(nil, 1, types, &reply);
-
- if (reply.sfGood)
- {
- DoNewSoundByte();
- window = (SoundByteWindowPtr)FrontWindow();
-
- do {
- if (window == nil) // sanity check
- break;
- window->resRef = FSpOpenResFile(&reply.sfFile, fsRdWrPerm);
- if (error = ResError())
- break;
- GetDItem((DialogPtr)window, iTopic, &kind, &item, &bounds);
- UseResFile(window->resRef);
- topicHandle = Get1Resource(kTopicResType, kTopicResID);
- SetIText(item, (StringPtr)*topicHandle);
- SelIText((DialogPtr)window, iTopic, 0, 254);
- window->state = kUnkownState;
- if (window->signature = Get1Resource(kSignatureResType, kSignatureResID))
- DetachResource(window->signature);
- if (window->sound = Get1Resource(kSoundResType, kSoundResID))
- DetachResource(window->sound);
- if (window->partOfName = Get1Resource(kNameResType, kNameResID))
- DetachResource(window->partOfName);
- } while (0);
-
- UseResFile(currentResFile);
- AlertOSErr(error);
- }
- }
-
- void DoFileMenu(short theItem)
- {
- switch (theItem)
- {
- case iNew:
- DoNewSoundByte();
- break;
- case iOpen:
- DoOpen();
- break;
- case iClose:
- DoClose();
- break;
- case iSave:
- DoSaving();
- break;
- case iQuit:
- gEnvironment.running = false;
- break;
- }
- }
-
- void DoEditMenu(short theItem)
- {
- DialogPtr dialog = FrontWindow();
-
- switch (theItem)
- {
- case iCut:
- ZeroScrap();
- if (dialog) DlgCut(dialog);
- break;
- case iCopy:
- ZeroScrap();
- if (dialog) DlgCopy(dialog);
- break;
- case iPaste:
- if (dialog) DlgPaste(dialog);
- break;
- case iSign:
- DoSigning();
- break;
- case iVerify:
- DoVerifying();
- break;
- }
- }
-
- void DoRecording()
- {
- OSErr error;
- Point loc = {0, 0};
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
-
- LocalToGlobal(&loc);
- loc.h += 75;
-
- if (window->sound)
- DisposHandle(window->sound);
-
- if ((window->sound = GetTempHandle()) == nil)
- error = MemError();
- else
- error = SndRecord(nil, loc, siGoodQuality, &window->sound);
-
- if (error == userCanceledErr && window->sound)
- {
- DisposHandle(window->sound);
- window->sound = nil;
- }
-
- if (window->state != kUnkownState)
- {
- window->state = kUnkownState;
- DrawDialog((DialogPtr)window);
- }
-
- AlertOSErr(error);
- }
-
- void DoPlaying()
- {
- OSErr error;
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
-
- error = SndPlay(nil, window->sound, true);
-
- AlertOSErr(error);
- }
-
- void DoSoundByteMenu(short theItem)
- {
- switch (theItem)
- {
- case iRecord:
- DoRecording();
- break;
- case iPlay:
- DoPlaying();
- break;
- }
- }
-
- void DoMenuChoice(long menuChoice)
- {
- short theMenu;
- short theItem;
-
- if (menuChoice != 0)
- {
- theMenu = hiword(menuChoice);
- theItem = loword(menuChoice);
- switch (theMenu)
- {
- case mApple:
- DoAppleMenu(theItem);
- break;
- case mFile:
- DoFileMenu(theItem);
- break;
- case mEdit:
- DoEditMenu(theItem);
- break;
- case mSoundByte:
- DoSoundByteMenu(theItem);
- break;
- }
- }
-
- HiliteMenu(0);
- }
-
- void AdjustMenus()
- {
- MenuHandle menu;
- SoundByteWindowPtr window = (SoundByteWindowPtr)FrontWindow();
-
- if (window)
- {
- menu = GetMHandle(mFile);
- EnableItem(menu, iClose);
- EnableItem(menu, iSave);
-
- menu = GetMHandle(mEdit);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iPaste);
- EnableItem(menu, iSign);
- window->signature ? EnableItem(menu, iVerify) : DisableItem(menu, iVerify);
-
- menu = GetMHandle(mSoundByte);
- EnableItem(menu, iRecord);
- window->sound ? EnableItem(menu, iPlay) : DisableItem(menu, iPlay);
- }
- else
- {
- menu = GetMHandle(mFile);
- DisableItem(menu, iClose);
- DisableItem(menu, iSave);
-
- menu = GetMHandle(mEdit);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iPaste);
- DisableItem(menu, iSign);
- DisableItem(menu, iVerify);
-
- menu = GetMHandle(mSoundByte);
- DisableItem(menu, iRecord);
- DisableItem(menu, iPlay);
- }
-
- }
-
- void DoMouseDown(EventRecord *event)
- {
- WindowPtr whichWindow;
- short thePart;
- long menuChoice;
-
- thePart = FindWindow(event->where, &whichWindow);
-
- switch (thePart)
- {
- case inMenuBar:
- AdjustMenus();
- menuChoice = MenuSelect(event->where);
- DoMenuChoice(menuChoice);
- break;
- case inSysWindow:
- SystemClick(event, whichWindow);
- break;
- case inDrag:
- DragWindow(whichWindow, event->where, &qd.screenBits.bounds);
- break;
- case inGoAway:
- if (TrackGoAway(whichWindow, event->where))
- DoClose();
- break;
- case inContent:
- SelectWindow(whichWindow);
- break;
- case inDesk:
- break;
- }
- }
-
- void DoKeyDown(EventRecord *event)
- {
- char charCode;
- long menuChoice;
-
- if (event->modifiers & cmdKey)
- {
- charCode = event->message & charCodeMask;
- if (charCode != 0)
- {
- AdjustMenus();
- menuChoice = MenuKey(charCode);
- DoMenuChoice(menuChoice);
- }
- }
- }
-
- void DoOSEvent(EventRecord *event)
- {
- unsigned char eventType;
-
- eventType = (unsigned char) (event->message >> 24) & 0x00ff;
-
- if (eventType == kSuspendResumeMessage)
- gEnvironment.inBackground = (event->message & kResumeMask) == 0;
- }
-
- Boolean DoDialogEvent(EventRecord *event)
- {
- short item;
- DialogPtr dialog;
- Boolean handleEvent = true;
- SoundByteWindowPtr window;
-
- if (DialogSelect(event, &dialog, &item))
- {
- if (!(event->what == keyDown && event->modifiers & cmdKey))
- {
- handleEvent = false;
- window = (SoundByteWindowPtr)dialog;
- if (window->state != kUnkownState)
- {
- window->state = kUnkownState;
- DrawDialog(dialog);
- }
- }
- }
-
- return handleEvent;
- }
-
- void EventLoop()
- {
- EventRecord event;
- Boolean handleEvent;
-
- handleEvent = WaitNextEvent(everyEvent, &event, kMinSleep, kNilMouseRgn);
-
- if (IsDialogEvent(&event))
- handleEvent = DoDialogEvent(&event);
-
- if (handleEvent)
- {
- switch (event.what)
- {
- case mouseDown:
- DoMouseDown(&event);
- break;
- case app4Evt:
- DoOSEvent(&event);
- break;
- case kHighLevelEvent:
- AEProcessAppleEvent(&event);
- break;
- case autoKey:
- case keyDown:
- DoKeyDown(&event);
- break;
- case activateEvt:
- case updateEvt:
- SetPort(FrontWindow());
- break;
- }
- }
- }
-
- void main()
- {
- BasicInitializations();
-
- if (Prerequisites())
- {
- ApplicationStartup();
- while (gEnvironment.running)
- EventLoop();
- }
- else
- DisplayUserAlert(kBadConfig, true, noErr);
- }
-
-